package v1

import (
	"gitee.com/CrazyMage/blog-service/global"
	"gitee.com/CrazyMage/blog-service/pkg/app"
	"gitee.com/CrazyMage/blog-service/pkg/errcode"
	"gitee.com/CrazyMage/blog-service/pkg/pay"
	"gitee.com/CrazyMage/blog-service/pkg/util"
	"github.com/gin-gonic/gin"
	"github.com/smartwalle/alipay/v3"
	"log"
)

type Pay struct{}

func NewPay() Pay {
	return Pay{}
}

func (t Pay) PreCreate(c *gin.Context) {
	var param pay.PreCreateReq
	valid, errs := app.BindAndValid(c, &param)
	aliPayClient, err := pay.NewAliPayClient(c.Request.Context())
	response := app.NewResponse(c)

	if !valid {
		global.Logger.Errorf(c, "app.BindAndValid errs: %v", errs)
		response.ToErrorResponse(errcode.InvalidParams.WithDetails(errs.Errors()...))
		return
	}

	create, err := aliPayClient.PreCreate(&param)
	if err != nil {
		global.Logger.Errorf(c, "aliPayClient.PreCreate errs: %v", err)
		log.Println(err)
		response.ToResponse(err)
		return
	}
	create.QRCode, _ = util.GenerateQRCodeToBase64(create.QRCode, 200)
	response.ToResponse(create)

}

func (t Pay) Query(c *gin.Context) {
	var param pay.QueryReq
	valid, errs := app.BindAndValid(c, &param)
	aliPayClient, err := pay.NewAliPayClient(c.Request.Context())
	response := app.NewResponse(c)

	if !valid {
		global.Logger.Errorf(c, "app.BindAndValid errs: %v", errs)
		response.ToErrorResponse(errcode.InvalidParams.WithDetails(errs.Errors()...))
		return
	}

	query, err := aliPayClient.Query(&param)
	if err != nil {
		global.Logger.Errorf(c, "aliPayClient.PreCreate errs: %v", err)
		log.Println(err)
		response.ToResponse(err)
		return
	}
	response.ToResponse(query)

}

func (t Pay) Fund(c *gin.Context) {
	var param pay.RefundReq
	valid, errs := app.BindAndValid(c, &param)
	aliPayClient, err := pay.NewAliPayClient(c.Request.Context())
	response := app.NewResponse(c)

	if !valid {
		global.Logger.Errorf(c, "app.BindAndValid errs: %v", errs)
		response.ToErrorResponse(errcode.InvalidParams.WithDetails(errs.Errors()...))
		return
	}

	refund, err := aliPayClient.Refund(&param)
	if err != nil {
		global.Logger.Errorf(c, "aliPayClient.PreCreate errs: %v", err)
		log.Println(err)
		response.ToResponse(err)
		return
	}

	response.ToResponse(refund)

}

func (t Pay) FundQuery(c *gin.Context) {
	var param pay.RefundQueryReq
	valid, errs := app.BindAndValid(c, &param)
	aliPayClient, err := pay.NewAliPayClient(c.Request.Context())
	response := app.NewResponse(c)

	if !valid {
		global.Logger.Errorf(c, "app.BindAndValid errs: %v", errs)
		response.ToErrorResponse(errcode.InvalidParams.WithDetails(errs.Errors()...))
		return
	}

	refundquery, err := aliPayClient.RefundQuery(&param)
	if err != nil {
		global.Logger.Errorf(c, "aliPayClient.PreCreate errs: %v", err)
		log.Println(err)
		response.ToResponse(err)
		return
	}

	response.ToResponse(refundquery)
}

func (t Pay) Notify(c *gin.Context) {

	//1.解析参数
	err := c.Request.ParseForm()
	if err != nil {
		global.Logger.Errorf(c, "app.ParseForm errs: %v", err)
		return
	}
	response := app.NewResponse(c)

	//2.声明客户端
	aliPayClient, err := pay.NewAliPayClient(c.Request.Context())
	if err != nil {
		global.Logger.Errorf(c, "pay.NewAliPayClient errs: %v", err)
		log.Println(err)
		return
	}
	ap := aliPayClient.GetOriginalClient()

	//3.验签得到消息，DecodeNotification 内部已调用 VerifySign 方法验证签名
	noti, err := ap.DecodeNotification(c.Request.Form)

	if err != nil {
		global.Logger.Errorf(c, "aliPayClient.DecodeNotification errs: %v", err)
		log.Println(err)
		response.ToResponse(err)
	}

	//3.业务处理
	log.Println(noti)

	//4.如果通知消息没有问题，我们需要确认收到通知消息，不然支付宝后续会继续推送相同的消息
	alipay.ACKNotification(c.Writer)

}
